package cn.share.life.module.images.utils.flowFile;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.share.life.common.util.StringUtils;
import com.google.common.collect.Maps;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FilenameUtils;

import java.io.File;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class FlowFileMain {

    public static void main(String[] args) {
        String basePath = "E:/kuaqu2/";
        String flowName = "龙政直流";
//        String dataType = "工程项目类"; // 工程类或非工程类
        String excelPath = "F:/公司3/2.2024年专项工程定价成本监审调查表-青豫直流0227.xlsx"; // Excel 文件路径
        String fileNameMappingPath = "F://公司3/28扎青-文件目录及文号V0.3.xlsx"; // 文件名映射路径
        List<File> imageFiles = getImageFileList(basePath);
        List<String> lineAreaList = FlowEnums.getByName(flowName);
        // 获取 2.2024年专项工程定价成本监审调查表
        Map<String, List<ProjectEntity>> dataMap = getProjectEntityList(excelPath);
        // 获取文件名映射
        List<String> numberRegexList = Lists.newArrayList();
        Map<String, FileMapping> projectFileMappingMap = getFileMapping("工程项目类", fileNameMappingPath, numberRegexList);
        Map<String, FileMapping> unProjectFileMappingMap = getFileMapping("非工程项目类", fileNameMappingPath, numberRegexList);
        // 特殊
        numberRegexList.add("[…]京会兴鉴字第……号");

        List<ItemEntity> projectItemEntityList = Lists.newArrayList();
        List<ItemEntity> unProjectItemEntityList = Lists.newArrayList();
        for (File file : imageFiles) {
            String name = file.getName();
            String path = file.getPath();
            path = path.replace("\\", "/"); // 替换为正斜杠
            // 这里可以添加一些测试代码来验证 ItemEntity 类的功能
            ItemEntity item = new ItemEntity();
            item.setFileOriginalName(name);
            item.setFileName(removeStrNumberAndPoint(name));  // 文件名称

            // 文件名字中包含的，xxxx11号，有固定规则
            String fileNumber = NumberEnums.getNumber(name, numberRegexList);
            item.setFileNumber(fileNumber);
            // 专项工程
            item.setSpecialProject(flowName);
            item.setFileName(item.getFileName().replace(fileNumber, ""));

            item.setFileSize(file.length() + "");
            item.setFileType(FilenameUtils.getPrefix(name).toLowerCase());
            item.setOfflineFileDirectory(path.replace(basePath, ""));

            FileMapping fileMapping = projectFileMappingMap.get(path);
            if (fileMapping != null) {
                // 标准文件库类型对应的线下文件目录
                String standardFileType = fileMapping.getStandardFileType();
                item.setStandardFileType(standardFileType);
                // 标准文件库类型（名字必须标准）
                item.setStandardFileDirectory(fileMapping.getStandardFileDirectory());

                // 后续投资/综合计划文件
                if (standardFileType.equals("后续投资/综合计划文件")) {
                    String areaByFlowName = getAreaByFlowName(name);
                    if (StringUtils.isNotEmpty(areaByFlowName)) {
                        boolean isAreaMatched = false;
                        for (String line: lineAreaList) {
                            if (StringUtils.isNotEmpty(line) && areaByFlowName.contains(line)) {
                                isAreaMatched = true;
                                break;
                            }
                        }
                        if (!isAreaMatched) {
                            item.setSpecialProject("-");
                        }
                    } else {
                        item.setSpecialProject("-");
                    }
                }

                // 工程类
                item.setDataType("工程项目类");
                item.setParentProjectName("");
                Map<String, String> projectMap = getProjectInfo(name, dataMap, fileNumber);
                item.setProjectName(projectMap.getOrDefault("projectName", ""));
                item.setProjectYear(projectMap.getOrDefault("projectYear", ""));

                projectItemEntityList.add(item);
            }

            // 非工程类
            fileMapping = unProjectFileMappingMap.get(path);
            if (fileMapping != null){
                item.setDataType("非工程项目类");

                // 标准文件库类型对应的线下文件目录
                String standardFileType = fileMapping.getStandardFileType();
                item.setStandardFileType(standardFileType);
                // 标准文件库类型（名字必须标准）
                item.setStandardFileDirectory(fileMapping.getStandardFileDirectory());

                String yearByFlowName = getYearByFlowName(name);
                if (StringUtils.isNotEmpty(yearByFlowName)) {
                    item.setYear(yearByFlowName);
                } else {
                    item.setYear(getYearByFlowName(file.getParentFile().getName()));
                }
                item.setCustomDirectorySuggestion("");// 空

                unProjectItemEntityList.add(item);
            }
        }
        writeExcel(projectItemEntityList, "工程项目类");
        writeExcel(unProjectItemEntityList, "非工程项目类");
        System.out.println(imageFiles);
    }

    private static Map<String, FileMapping> getFileMapping(String dataType, String fileNameMappingPath, List<String> numberRegexList) {
        String sheetName = dataType.equals("工程项目类") ? "专项工程_工程项目类" : "专项工程_非工程项目类";
        List<List<Object>> listList = ExcelUtil.getReader(new File(fileNameMappingPath), sheetName).read(1);

        List<FileMapping> mappingList = new ArrayList<>();
        for (List<Object> row : listList) {
            FileMapping fileMapping = new FileMapping();
            String path = String.valueOf(row.get(0));
            if (StringUtils.isEmpty(path)) {
                continue; // 跳过空路径
            }
            fileMapping.setOfflineFileDirectory(path);
            fileMapping.setStandardFileDirectory(String.valueOf(row.get(2)));
            fileMapping.setStandardFileType(String.valueOf(row.get(1)));
            mappingList.add(fileMapping);
        }

        if (CollectionUtils.isEmpty(numberRegexList)) {
            // 文号
            listList = ExcelUtil.getReader(new File(fileNameMappingPath), "文号").read(1);
            for (List<Object> row : listList) {
                numberRegexList.add(String.valueOf(row.get(0)));
            }
        }
        return mappingList.stream().collect(Collectors.toMap(FileMapping::getOfflineFileDirectory, fileMapping -> fileMapping, (existing, replacement) -> existing));
    }

    private static Map<String, String> getProjectInfo(String name, Map<String, List<ProjectEntity>> dataMap, String number) {
        Map<String, String> result = Maps.newHashMap();

        for (Map.Entry<String, List<ProjectEntity>> entry : dataMap.entrySet()) {
            String key = entry.getKey();
            List<ProjectEntity> projectEntities = entry.getValue();

            if (StringUtils.isNotEmpty(number) && key.contains(number)) {
                result.put("projectName", projectEntities.stream().map(ProjectEntity::getProjectName).collect(Collectors.joining(",")));
                result.put("projectYear", projectEntities.stream().map(ProjectEntity::getCommissioningDate).collect(Collectors.joining(",")));
                return result;
            }

            if (key.contains(name)) {
                result.put("projectName", projectEntities.stream().map(ProjectEntity::getProjectName).collect(Collectors.joining(",")));
                result.put("projectYear", projectEntities.stream().map(ProjectEntity::getCommissioningDate).collect(Collectors.joining(",")));
                return result;
            }

            // 去掉中文括号和英文括号再比较
            String cleanedKey = key.replace("（", "").replace("）", "").replace("(", "").replace(")", "");
            String cleanedNumber = number.replace("（", "").replace("）", "").replace("(", "").replace(")", "");
            if (cleanedKey.contains(cleanedNumber)) {
                result.put("projectName", projectEntities.stream().map(ProjectEntity::getProjectName).collect(Collectors.joining(",")));
                result.put("projectYear", projectEntities.stream().map(ProjectEntity::getCommissioningDate).collect(Collectors.joining(",")));
                return result;
            }
        }
        return result;
    }

    private static void writeExcel(List<ItemEntity> itemEntityList, String dataType) {
        List<List<String>> rows = Lists.newArrayList();
        List<String> header = Lists.newArrayList("序号", "文件原名", "文件名", "文件号", "专项工程", "标准文件库类型", "标准文件库类型对应的线下文件目录", "年份", "自定义目录建议", "文件大小", "文件类型",
                "线下文件目录");
        if (dataType.equals("工程项目类")) {
            header = Lists.newArrayList("序号", "文件原名", "文件名", "文件号", "标准文件库类型", "标准文件库类型对应的线下文件目录", "文件大小", "文件类型", "专项工程",
                    "项目名称", "父项目名称", "项目投运年度", "线下文件目录");
        }
        rows.add(header);
        int index = 0;
        for (ItemEntity item : itemEntityList) {
            List<String> row = Lists.newArrayList();
            row.add(index++ + ""); // 序号
            row.add(item.getFileOriginalName());
            row.add(item.getFileName());
//            row.add(item.getDataType());
            row.add(item.getFileNumber());
            // "序号", "文件原名", "文件名", "文件号", "标准文件库类型", "标准文件库类型对应的线下文件目录", "文件大小", "文件类型", "专项工程",
            //                    "项目名称", "父项目名称", "项目投运年度", "线下文件目录"
            if (dataType.equals("工程项目类")) {

                row.add(item.getStandardFileType());
                row.add(item.getStandardFileDirectory());
                row.add(item.getFileSize());
                row.add(item.getFileType());
                row.add(item.getStandardFileDirectory());

                row.add(item.getProjectName());
                row.add(item.getParentProjectName());
                row.add(item.getProjectYear());
            } else if (!dataType.equals("工程项目类")) {
                // "序号", "文件原名", "文件名", "文件号", "专项工程", "标准文件库类型", "标准文件库类型对应的线下文件目录", "年份", "自定义目录建议", "文件大小", "文件类型",
                //                "线下文件目录"
                row.add(item.getSpecialProject());
                row.add(item.getStandardFileType());
                row.add(item.getStandardFileDirectory());

                row.add(item.getYear());
                row.add(item.getCustomDirectorySuggestion());
                row.add(item.getFileSize());
                row.add(item.getFileType());
            }
            row.add(item.getOfflineFileDirectory());
            rows.add(row);
        }
        // 写入 Excel 文件
        String outputFilePath = "E:/kuaqu2/output_" + dataType + ".xlsx"; // 输出文件路径
        ExcelWriter writer = ExcelUtil.getWriter(outputFilePath)
                .write(rows, true);
        writer.getCellStyle().setWrapText(true); // 设置单元格文本换行
        // 设置列宽
        for (int i = 0; i < header.size(); i++) {
            writer.setColumnWidth(i, 30); // 设置每列宽度为20
        }
        //关闭writer，释放内存
        writer.close();
    }

    public static List<File> getImageFileList(String path) {
        List<File> fileList = new ArrayList<>();
        File directory = new File(path);
        if (directory.exists() && directory.isDirectory()) {
            for (File file : Objects.requireNonNull(directory.listFiles())) {
                if (file.isDirectory()) {
                    fileList.addAll(getImageFileList(file.getAbsolutePath()));
                } else {
//                    String name = file.getName();
//                    String areaByFlowName = getAreaByFlowName(name);
//                    if (StringUtils.isNotEmpty(areaByFlowName) && !areaList.contains(areaByFlowName)) {
//                        // 如果文件名中包含括号内的区域名称，并且该区域在 areaList 中，则添加到列表
//                        System.out.println("未匹配到文件: " + file.getAbsolutePath());
//                        continue;
//                    }
                    fileList.add(file);
                }
            }
        }
        return fileList;
    }

    public static String getAreaByFlowName(String name) {

        if (StringUtils.isNotEmpty(name) && !name.contains("（") && !name.contains("）") && !name.contains("(") && !name.contains(")")) {
            // 如果文件名中包含括号，则提取括号内的内容
            return "";
        }
        if (StringUtils.isEmpty(name)) {
            return "";
        }

        name = name.replace("(", "（").replace(")", "）"); // 替换英文括号为中文括号

        String regex = "（([^)]+)）"; // 小括号正则表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(name);

        if (matcher.find()) {
            return matcher.group(1);
        }

        return null;
    }

    public static String getYearByFlowName(String name) {
        String regex = "20\\d{2}"; // 小括号正则表达式
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(name);

        if (matcher.find()) {
            System.out.println(matcher.group()); // 输出括号内的内容
            return matcher.group();
        }
        return null;
    }

    // 项目信息表
    public static Map<String, List<ProjectEntity>> getProjectEntityList(String excelPath) {
        List<List<Object>> listList = ExcelUtil.getReader(new File(excelPath), "表3-2 投资明细表").read(5, 80);

        List<ProjectEntity> projectEntities = new ArrayList<>();
        for (List<Object> row : listList) {
            ProjectEntity projectEntity = new ProjectEntity();
            projectEntity.setDataSource(String.valueOf(row.get(2))); // 数据来源
            projectEntity.setCommissioningDate(String.valueOf(row.get(3))); // 投产日期
            projectEntity.setProjectName(String.valueOf(row.get(7))); // 项目名称

            // 投产年份
            projectEntity.setCommissioningDate(projectEntity.getCommissioningDate().split("年")[0]);
            if (StringUtils.isNotEmpty(projectEntity.getDataSource())) {
                projectEntities.add(projectEntity);
            }
        }

        return projectEntities.stream().collect(Collectors.groupingBy(ProjectEntity::getDataSource));
    }

    // 祛除序号
    public static String removeStrNumberAndPoint(String str) {
        // 使用正则表达式分割字符串
        String[] parts = str.split("/");
        // 创建一个 StringBuilder 来存储结果
        StringBuilder result = new StringBuilder();

        // 遍历每个部分，去除序号
        for (String part : parts) {
            // 去除序号
            String cleanedPart = part.replaceAll("^\\d+\\.\\s*", "");
            // 将处理后的部分添加到结果中
            result.append(cleanedPart).append("/");
        }

        // 去掉最后一个多余的斜杠
        if (result.length() > 0) {
            result.setLength(result.length() - 1);
        }
        return result.toString();
    }
}
